<?php

namespace app\controller\app\wechat;

use app\common\Sign;
use app\common\Util;
use App\model\AppModel;
use App\model\UserModel;
use app\service\Async;
use app\service\ExceptionService;
use App\service\LoginRecord;
use support\facade\Locker;
use support\Request;
use think\facade\Cache;
use app\service\Route;
use think\facade\Db;
use Webman\RedisQueue\Client;

class Xcx
{
    protected $app_id = 0;
    protected $user_id = 0;
    protected $access_token = '';
    protected $authority=[];

    public function beforeAction(Request $request){

        $_app_id = $request->header('appid');
        $_access_token = $request->header('authorization');

        if (!isset($_app_id)) {
            return error(2, 'app_id is null');
        }
        $this->access_token = $_access_token;
        $this->app_id=$_app_id;

        $payload = Sign::decode($this->access_token,config('app.jwt_sign'));
        if($payload){
            if(isset($payload['uid'])){
                $this->user_id = $payload['uid'];
            }
            $this->authority = Cache::get('auth_'.$this->user_id);
        }
    }

    public function decryptData($appid, $sessionKey, $encryptedData, $iv, &$data) {
        if (strlen($sessionKey) != 24) {
            return -41001;
        }
        $aesKey = base64_decode($sessionKey);


        if (strlen($iv) != 24) {
            return -41002;
        }
        $aesIV = base64_decode($iv);

        $aesCipher = base64_decode($encryptedData);

        $result = openssl_decrypt($aesCipher, "AES-128-CBC", $aesKey, 1, $aesIV);

        $dataObj = json_decode($result);
        if ($dataObj == NULL) {
            return -41003;
        }
        if ($dataObj->watermark->appid != $appid) {
            return -41003;
        }
        $data = $result;
        return 0;
    }

    /**
     * @Route(reqUrl="/app.xcx.getUserInfo")
     */
    public function getUserInfo(Request $request){
        $xcx = AppModel::where([['app_id','=',$this->app_id]])->find();
        $code=input('code');
        $_reqUrl = "https://api.weixin.qq.com/sns/jscode2session?appid=" . $xcx['xcx_app_id'] . "&secret=" . $xcx['xcx_app_secret'] . "&js_code={$code}&grant_type=authorization_code";
        $res = json_decode(Util::get($_reqUrl), true);
//        var_dump($res);
        $openid=$res['openid'] ?? '';
        $unionid=$res['unionid'] ?? '';

        $userObj = new UserModel([],$this->app_id);
        $where=[];
        $where['wechat_xcx_openid'] = $openid;
        $where['useable'] = 1;
        $user = $userObj->where($where)->find();
        if($user){
            $user =  $userObj->info($user['user_id']);
            $iat = time();
            $payload = [
                'iss' => config('app.app_name'), //签发者
                'iat' => $iat, //什么时候签发的
                'exp' => $iat + 60*60*24*365, //过期时间()
                'uid' => $user['user_id']
            ];
            $client_ip = $request->getRealIp($safe_mode=true);
            $jwt = Sign::encode($payload, config('app.jwt_sign'));
            $user['access_token'] = $jwt;
            Cache::set('auth_'.$user['user_id'],$userObj->info($user['user_id']),60*60*24*365);
            LoginRecord::add('openidLogin',$openid,'success',$client_ip,$this->app_id);
            $rtn['userInfo']=$user;
        }
        else{
            $rtn['userInfo']=null;
        }

        $rtn['openId']=$openid;
        $rtn['unionId']=$unionid;
        return success($rtn);
    }

    /**
     * @Route(reqUrl="/app.xcx.getOpenId")
     */
    public function getOpenId(Request $request){
        $xcx = AppModel::where([['app_id','=',$this->app_id]])->find();
        $code=input('code');
        $_reqUrl = "https://api.weixin.qq.com/sns/jscode2session?appid=" . $xcx['xcx_app_id'] . "&secret=" . $xcx['xcx_app_secret'] . "&js_code={$code}&grant_type=authorization_code";
        $res = json_decode(Util::get($_reqUrl), true);
        $openid=$res['openid'] ?? '';
        $unionid=$res['unionid'] ?? '';
        $rtn['openId']=$openid;
        $rtn['unionId']=$unionid;
        return success($rtn);
    }

    /**
     * @Route(reqUrl="/app.xcx.binding")
     */
    public function binding(Request $request){
        if(input('mobile')==null){
            return error(0,"手机号码不能为空");
        }
        if(input('code')==null){
            return error(0,"验证码不能为空");
        }
        $code=input('code');
        $mobile=input('mobile');
        $referrerId=input('referrerId',0);
        $wxxcxInfo=json_decode(input('wxxcxInfo'),true) ?? [];
        if($code==Cache::get($mobile.'_captcha')){
            $userObj = new UserModel([],$this->app_id);
            $where=[];
            $where['mobile'] = $mobile;
            $where['useable'] = 1;
            $where['app_id'] = [$this->app_id];
            $user = $userObj->where($where)->find();
            if($user){
                if($user['wechat_xcx_openid']){
                    return error(1,"手机号码已被使用");
                }
                else{
                    $userObj->where('user_id','=',$user['user_id'])->update(['wechat_xcx_openid'=>$wxxcxInfo['openId'],'wechat_unionid'=>$wxxcxInfo['unionId'],'edt_time'=>time()]);
                    $user =  $userObj->info($user['user_id']);
                    $iat = time();
                    $payload = [
                        'iss' => config('app.app_name'), //签发者
                        'iat' => $iat, //什么时候签发的
                        'exp' => $iat + 60*60*24*365, //过期时间()
                        'uid' => $user['user_id']
                    ];
                    $jwt = Sign::encode($payload, config('app.jwt_sign'));
                    $user['access_token'] = $jwt;
                    Cache::set('auth_'.$user['user_id'],$userObj->info($user['user_id']),60*60*24*365);
                    return success($user,0,'绑定成功');
                }
            }
            else{
                $lock = Locker::userAdd($mobile);
                if(!$lock->acquire()){
                    return error(1,'操作太频繁,请稍后再试');
                }
                Db::startTrans();
                try {
                    $_user=[];
                    $_user['referrer_id'] = $referrerId;
                    $_user['username']=$wxxcxInfo['nickName'];
                    $_user['avatar']=$wxxcxInfo['avatarUrl'];
                    $_user['app_id']=$this->app_id;
                    $_user['level_id']=0;
                    $_user['group_id'] = 0;
                    $_user['password']=md5($mobile);
                    $_user['mobile']=$mobile;
                    $_user['wechat_xcx_openid']=$wxxcxInfo['openId'];
                    $_user['wechat_unionid']=$wxxcxInfo['unionId'];
                    $_user['add_time']=time();

                    $user_id = $userObj->insertGetId($_user);
                    Db::commit();
                    Async::Do(UserModel::class,'uploadAvatar',$user_id);
                    $user =  $userObj->info($user_id);
                    $iat = time();
                    $payload = [
                        'iss' => config('app.app_name'), //签发者
                        'iat' => $iat, //什么时候签发的
                        'exp' => $iat + 60*60*24*365, //过期时间()
                        'uid' => $user['user_id']
                    ];
                    $jwt = Sign::encode($payload, config('app.jwt_sign'));
                    $user['access_token'] = $jwt;
                    Cache::set('auth_'.$user['user_id'],$userObj->info($user['user_id']),60*60*24*365);
                    return success($user,0,'绑定成功');
                } catch (\Exception $e) {
                    ExceptionService::addLog($e,"#FE4A26");
                    Db::rollback();
                    return error(1,"绑定失败");
                } finally {
                    $lock->release();
                }
            }
        }
        else{
            return error(1,"验证码错误");
        }
    }
}